package com.tlgen.select;

import com.sun.tools.javac.api.JavacTrees;
import com.sun.tools.javac.code.Flags;
import com.sun.tools.javac.processing.JavacProcessingEnvironment;
import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.tree.TreeMaker;
import com.sun.tools.javac.util.*;

import javax.annotation.processing.ProcessingEnvironment;
import javax.lang.model.element.Element;

public class MyDataProcessor {
    private TreeMaker treeMaker;
    private Names names;

    public MyDataProcessor(ProcessingEnvironment processingEnv) {
        Context context = ((JavacProcessingEnvironment) processingEnv).getContext();
        treeMaker = TreeMaker.instance(context);
        names = Names.instance(context);
    }

    /**
     * 导入一个包
     *
     * @param importClass 要导入的包
     */
    public void importPackage(JavacTrees trees, Element element, String importClass) {
        JCTree.JCCompilationUnit compilationUnit = (JCTree.JCCompilationUnit) trees.getPath(element).getCompilationUnit();
        JCTree.JCFieldAccess fieldAccess = treeMaker.Select(treeMaker.Ident(
                        names.fromString(importClass.substring(0, importClass.lastIndexOf(".")))),
                names.fromString(importClass.substring(importClass.lastIndexOf(".") + 1)));
        JCTree.JCImport jcImport = treeMaker.Import(fieldAccess, false);
        ListBuffer<JCTree> imports = new ListBuffer<>();
        imports.append(jcImport);
        for (int i = 0; i < compilationUnit.defs.size(); i++) {
            imports.append(compilationUnit.defs.get(i));
        }
        compilationUnit.defs = imports.toList();
    }

    public JCTree.JCMethodDecl genSelectByMethod(JCTree.JCVariableDecl jcVariableDecl, JCTree.JCClassDecl jcClassDecl) {
        Name className = jcClassDecl.name;
        // 方法参数
        JCTree.JCVariableDecl param = treeMaker.VarDef(
                // 访问修饰符
                treeMaker.Modifiers(Flags.PARAMETER, List.nil()),
                // 变量名
                names.fromString("value"),
                // 变量类型
                treeMaker.Ident(names.fromString("Object")),
                // 变量初始值
                null
        );
        //  return Model.select(new QueryOperator<SysUser>().eq("username", value), SysUser.class);
        // 构造方法的返回类型 List<SysUser>
        JCTree.JCTypeApply returnType = treeMaker.TypeApply(
                treeMaker.Ident(names.fromString("List"))
                , List.of(treeMaker.Ident(names.fromString(className.toString())))
        );
        // public 方法访问级别修饰
        JCTree.JCModifiers modifiers = treeMaker.Modifiers(Flags.PUBLIC + Flags.STATIC);
        // 方法名
        Name selectMethodName = createselectByMethodName(jcVariableDecl.getName());
        // 泛型参数列表
        List<JCTree.JCTypeParameter> methodGenericParamList = List.nil();
        // 参数值列表
        List<JCTree.JCVariableDecl> parameterList = List.of(param);
        // 异常抛出列表
        List<JCTree.JCExpression> throwCauseList = List.nil();

        ListBuffer<JCTree.JCStatement> statements = new ListBuffer<JCTree.JCStatement>();

        // 返回 ret
        JCTree.JCReturn returnStatement = treeMaker.Return(
                treeMaker.Apply(List.nil(),
                        treeMaker.Select(
                                treeMaker.Ident(names.fromString("Model")),
                                names.fromString("select")
                        ),
                        List.of(
                                treeMaker.Apply(List.nil(),
                                        treeMaker.Select(
                                                treeMaker.NewClass(
                                                        null,
                                                        com.sun.tools.javac.util.List.nil(),
                                                        treeMaker.Ident(names.fromString("QueryOperator")),
                                                        com.sun.tools.javac.util.List.nil(),
                                                        null
                                                )
                                                ,
                                                names.fromString("eq")
                                        ),
                                        List.of(treeMaker.Literal(jcVariableDecl.getName().toString()),
                                                treeMaker.Ident(names.fromString("value")))
                                )

                                ,
                                treeMaker.Select(
                                        treeMaker.Ident(names.fromString(className.toString())),
                                        names.fromString("class")))
                )
        );

        statements.append(returnStatement);
        JCTree.JCBlock body = treeMaker.Block(0, statements.toList());

        // 生成方法定义树节点
        return treeMaker.MethodDef(
                // 方法访问级别修饰符
                modifiers,
                // 方法名
                selectMethodName,
                // 返回值类型
                returnType,
                // 泛型参数列表
                methodGenericParamList,
                //参数值列表
                parameterList,
                // 异常抛出列表
                throwCauseList,
                // 方法默认体
                body,
                // 默认值
                null
        );
    }


    /**
     * selectByUsername
     *
     * @param variableName
     * @return
     */
    private Name createselectByMethodName(Name variableName) {
        String fieldName = variableName.toString();
        return names.fromString("selectBy" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1));
    }

}
